package com.tender.shiro.filter;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import com.tender.jwt.JwtTokenManager;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import com.tender.constants.Constants;
import com.tender.common.Result;

/**
 * 表单认证过滤器的自定义
 */
public class JwtAuthenticationFilter extends FormAuthenticationFilter {

    private JwtTokenManager jwtTokenManager;

    public JwtAuthenticationFilter(JwtTokenManager jwtTokenManager) {
        this.jwtTokenManager = jwtTokenManager;
    }

    /**
     * @Description 是否允许访问
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        // 判断当前请求头(header)是否带有 jwtToken 的字符串
        String jwtToken = WebUtils.toHttp(request).getHeader(Constants.AUTHORIZATION_HEADER);
        // 如果有：走jwt校验
        if (StringUtils.isNotBlank(jwtToken)) {
            boolean verifyToken = jwtTokenManager.isVerifyToken(jwtToken);
            if (verifyToken) {
                // jwt 有效，则走父类中的 isAccessAllowed 方法
                return super.isAccessAllowed(request, response, mappedValue);
            } else {
                return false;
            }
        }

        //没有没有：走原始校验
        return super.isAccessAllowed(request, response, mappedValue);
    }

    /**
     * @Description 访问拒绝时调用
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        //判断当前请求头中是否带有jwtToken的字符串
        String jwtToken = WebUtils.toHttp(request).getHeader(Constants.AUTHORIZATION_HEADER);
        //如果有：返回json的应答
        if (StringUtils.isNotBlank(jwtToken)) {
            Result<Object> result = Result.of();
            result.setResultCode(Constants.NO_LOGIN_CODE);
            result.setResultMsg(Constants.NO_LOGIN_MESSAGE);
            response.setCharacterEncoding(Constants.UTF_8_ENCODING);
            response.setContentType(Constants.CONTENT_TYPE_WITH_UTF_8_AND_JSON);
            response.getWriter().write(JSON.toJSONString(result));
            return false;
        }
        //如果没有：走原始方式
        return super.onAccessDenied(request, response);
    }
}
